/**
  * 防抖函数：当被调用 n 毫秒后才会执行，如果在这时间内又被调用则将重新计算执行时间
  * @param {Function} callback 回调
  * @param {Number} wait 计时器间隔时间 单位：秒毫
  * @param {Boolean} leading 参数isLeading: 默认{true}表示在计时之前执行 {false}表示在计时之后执行
  * @return {Function}
  */
function debounce(callback, wait, leading = true) {
    var args = null
    var context = null
    var runFlag = false
    var timeout = null
    var isLeading = leading

    var runFn = function () {
        runFlag = true
        callback.apply(context, args)
        args = null
        context = null
    }

    var endFn = function () {
        if (isLeading) {
            timeout = null
        }
        if (!runFlag && !isLeading) runFn()
    }

    var cancelFn = function () {
        let rest = timeout !== null
        if (rest) {
            clearTimeout(timeout)
        }

        args = null
        context = null
        timeout = null

        runFlag = false

        return rest
    }

    var debounced = function () {
        runFlag = false
        args = arguments
        context = this
        if (timeout == null) {
            if (isLeading) runFn()
        } else {
            clearTimeout(timeout)
        }
        timeout = setTimeout(endFn, wait)
    }

    debounced.cancel = cancelFn

    return debounced

}

module.exports = debounce;